/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun<iot25@lingyun>
 *                  All rights reserved.
 *
 *       Filename:  popen.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(14/03/25)
 *         Author:  LingYun <iot25@lingyun>
 *      ChangeLog:  1, Release initial version on "14/03/25 20:11:23"
 *                 
 ********************************************************************************/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>

// 函数声明：获取指定网络接口的IP地址
int get_ipaddr(char *interface, char *ipaddr, int ipaddr_size);

int main(int argc, char *argv[])
{
	char 				ipaddr[16];// 用于存储IP地址的字符数组
	char 				*interface="eth0"; // 指定网络接口为eth0
	memset(ipaddr,0,sizeof(ipaddr));// 初始化ipaddr数组为0

	if( get_ipaddr(interface,ipaddr, sizeof(ipaddr))<0)// // 调用get_ipaddr函数获取IP地址
	{
		printf("ERROR: get IP address failure\n");
		return -1;
	}

	printf("get network interface %s IP address [%s]\n",interface,ipaddr);// 打印获取到的IP地址
	return 0;//返回值0
}
int get_ipaddr(char *interface, char *ipaddr, int ipaddr_size)
{
	char		buf[1024];//定义缓冲区buf
	char		*ptr;
	char		*ip_start;//定义起始地址指针
	char		*ip_end;//定义结束地址指针
	FILE		*fp;  //文件指针，用于读取输出命令
	int			len;
	int			rv;

	if( !interface || !ipaddr || ipaddr_size<16)//判断输入参数是否合法。
	{
		printf("Invalid input arguments\n");//无效输入参数
		return -1;
	}

	memset(buf,0, sizeof(buf));//初始化缓冲区为0
	snprintf(buf, sizeof(buf), "ifconfig %s", interface);// 构造命令字符串，使用ifconfig命令获取指定接口的信息
	if( NULL==( fp=popen(buf,"r")))//判断返回值，popen函数执行命令
	{
		printf("popen() to excute command \"%s\" failure:%s\n", buf,strerror(errno));// 如果执行失败，打印错误信息
		return -2;
	}

	rv=-3;/* Set default return value to -s means parser failure */
	
	//while循环，逐渐读取命令输出
	while( fgets(buf,sizeof(buf), fp))
	{
		if( strstr(buf,"netmask"))//strstr函数是C语言和C++标准库中的一个字符串查找函数，用于在主字符串中查找子字符串，并返回子字符串首次出现的位置。
		{
				ptr=strstr(buf, "inet");//查询inet字符串。
				if( !ptr )
				{
						break;
				}
				ptr += strlen("inet");// 移动指针到"inet"之后的位置

				while( isblank(*ptr) )//在Linux中，isblank 函数用于检查一个字符是否为空白字符。
					ptr++;

				ip_start = ptr;
				
				while( !isblank(*ptr) )
					ptr++;

				ip_end = ptr;
				memset(ipaddr,0,sizeof(ipaddr));//初始化ipaddr

				len = ip_end-ip_start;//ip_end到ip_start的长度
				len = len>ipaddr_size ? ipaddr_size:len;// 确保长度不超过ipaddr_size
				memcpy(ipaddr,ip_start,len);// 将IP地址复制到ipaddr数组
				
				rv = 0;
				break;
		}
	}
	return rv;
}

